package model;

import model.interfaces.selectable.SelectableCommand;
import model.interfaces.commandTypes.ArgumentsVisitor;
import model.interfaces.commandTypes.DirectionArgs;

/**
 * Command for an army to attack in a certain direction.
 * 
 * @author Christopher Dudley
 * @editor alex kagioglu
 */
class Attack implements Command, SelectableCommand, DirectionArgs, NotPartOfTheSystem
{
    private static final String name = "Attack"; // The name of all attack
                                                 // commands.
    private Direction argument; // The direction in which to attack.
    
    /**
     * Creates a new attack command with no direction.
     */
    public Attack() {
        argument = null;
    }
    
    private Attack( Direction dir ) {
        this.argument = dir;
    }
    
    /**
     * It's not part of your system!
     */
    public void throwItOnTheGround()
    {
        new ThrowItOnTheGround().cuzMyDadIsNotA( this );
    }
    
    /**
     * Executes the command.
     * 
     * @param player
     *            the player whose army is attacking.
     * @param instance
     *            the instance of the army that is attacking.
     */
    public void run( Player player, ModelInstance instance )
    {
        player.attack( instance, argument );
    }
    
    /**
     * Accepts an argument visitor so that the visitor can correctly set the
     * directional argument required by the command.
     * 
     * @param visitor
     *            the ArgumentsVisitor.
     */
    public void accept( ArgumentsVisitor visitor )
    {
        visitor.visitDirectionArgs( this );
    }
    
    /**
     * Returns the name of the command.
     * 
     * @return the name of the command.
     */
    public String getName()
    {
        String result = Attack.name;
        if ( this.argument != null ) result = result + " " + this.argument.dir;
        return result;
    }
    
    /**
     * Returns a Command version of itself that can be executed and resets the
     * current command's argument.
     * 
     * @return a command interface version of this command.
     */
    public Command getCommand()
    {
        Command result = new Attack( this.argument );
        this.argument = null;
        return result;
    }
    
    /**
     * Sets the directional argument required by the attack command.
     * 
     * @param dir
     *            the direction.
     */
    public void setArgs( Direction dir )
    {
        this.argument = dir;
    }
}
